iT邦幫忙

2024 iThome 鐵人賽

DAY 8
0
佛心分享-IT 人自學之術

洞察十倍工程師的內心世界系列 第 8

提升開發速度的關鍵:讓程式更容易被測試

  • 分享至 

  • xImage
  •  

學習要點

懂得如何寫出好測試的程式,對開發者技術能力提升有重大的影響。

故事描述

雖然一開始我成為測試開發工程師是個意外,我不得不在短時間內迅速補齊寫測試的技能,但沒想到這段經歷卻對我產生如此深遠的影響。

在這段期間,我寫了大量的測試程式。由於撰寫過很多測試,我能輕易區分哪些程式碼容易寫測試,哪些則較為困難。隨著我對撰寫測試程式的掌握日益熟練,我發現自己在其他方面的程式開發能力也隨之提升。

順帶一提,前一篇文章提到我在第二次接觸測試開發時,團隊曾得出「只能針對關鍵部分補寫測試,其餘部分暫時不管」的結論。當時的情況是,codebase 中多數程式都沒有遵循「單一職責原則」,且依賴外部資源或缺乏明確的輸出值。

如今,我在寫程式時會優先考慮如何撰寫易於測試的程式,而這個小小的思維改變,大大降低了寫出「一團義大利麵」式程式碼的可能性。

啟發

在經歷大量的測試開發後,我逐漸體會到,寫測試程式不僅能讓你快速發現問題,還能改變你寫程式的方式。測試驅動開發 (TDD) 並不只是一種工具,而是一種思維模式,讓你更有架構性地思考與開發程式。

實踐指南:寫出好測試的程式

要測試的程式邏輯是單純的純函數,依賴輸入與輸出,沒有外部依賴。

範例:好寫測試的函式

function add(a, b) {
    return a + b;
}

// 測試範例
const assert = require('assert');
assert.strictEqual(add(2, 3), 5); // 測試通過
assert.strictEqual(add(-1, 1), 0); // 測試通過

範例:不好寫測試的函式

// 要測的函式
function fetchUserData(userId) {
    const currentDate = new Date(); // 外部依賴
    const apiEndpoint = `https://api.example.com/users/${userId}`;
    
    return fetch(apiEndpoint)
        .then(response => response.json())
        .then(data => {
            return {
                user: data,
                fetchedAt: currentDate
            };
        });
}

// 測試範例
fetchUserData(1).then(data => {
    // 測試使用者資料是否正確
    assert.strictEqual(data.user.name, "John Doe");
    // 日期可能會變動,而影響測試結果。
    assert.strictEqual(data.fetchedAt.toISOString(), "......");
});

範例:改進「不好寫測試的函式」

// 要測的函式
function fetchUserData(userId, currentDate) {
    const apiEndpoint = `https://api.example.com/users/${userId}`;
    
    return fetch(apiEndpoint)
        .then(response => response.json())
        .then(data => {
            return {
                user: data,
                fetchedAt: currentDate
            };
        });
}

// 測試範例
const assert = require('assert');
const mockDate = new Date("2024-01-01");

fetchUserData(1, mockDate).then(data => {
    // 測試使用者資料是否正確
    assert.strictEqual(data.user.name, "John Doe");
    // 測試日期是否正確
    assert.strictEqual(data.fetchedAt.toISOString(), mockDate.toISOString());
});

理論

單一職責原則

單一職責原則(Single Responsibility Principle, SRP)是 SOLID 原則中的一部分,該原則強調每個函式或類別應該只有一個明確的責任。

當一個函式遵循這個原則時,寫測試會變得更加容易,因為你只需要測試它的單一功能,而不會被過多的外部依賴或複雜邏輯所干擾。

依賴倒置原則

依賴倒置原則(Dependency Inversion Principle, DIP)強調,高層模組不應該依賴於低層模組,兩者都應該依賴於抽象。

這意味著,我們可以使用「依賴注入」技術,將函式中的依賴(如 API 請求或時間)注入函式中,這樣在測試時就可以輕鬆地替換掉這些依賴。範例中,將 currentDate 作為參數注入的範例,正是依賴倒置原則的具體應用。


上一篇
提升開發速度的關鍵:從落實寫測試開始
下一篇
提升開發速度的關鍵:寫程式就像打怪,重點是回血速度
系列文
洞察十倍工程師的內心世界34
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言